mysql的varchar类型的字段,如果插入的数据超过设定的length,就会有问题,通常会有2种情况,第一种是报错,第二种是直接自动截取,那什么情况下会直接报错,什么情况下会自动截取呢?
答案是和数据库是否设置了严格模式有关
一.直接报错
我们先来看第一种情况,test_varchar长度是8,当我们通过客户端加长字符串时,会提示Maximum text length is set to 8.,顾名思义,就是字段超长了,不能再加了
那我们再通过直接insert语句来插入长度超过8的:
INSERT INTO `test123` (`text_varchar`) VALUES ('123456789---');
发现直接提示:Data too long for column 'text_varchar' at row 1
那如果是代码里调用,也会直接抛出这个异常
既然说了是否报错是取决于数据库是否设置了严格模式,我们来看看当前数据库的严格模式设置:
执行:select @@sql_mode,发现返回值如下:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
当返回值包含STRICT_TRANS_TABLES(存储引擎启用严格模式,非法数据值被拒绝)时,表示开启了严格模式,此时如果字段超长会直接报错
二.自动截取
我们将数据库模式改成非严格模式,即把sql_mode中的STRICT_TRANS_TABLES去掉:
SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
执行完之后重启客户端,再select @@sql_mode就发现STRICT_TRANS_TABLES已经没有了
我们再来进行操作,首先在客户端直接加,还是一样的提示Maximum text length is set to 8.
我们再来用insert语句来执行:
INSERT INTO `test123` (`text_varchar`) VALUES ('123456789---');
可以发现此时并没有报错并且插入成功了:
但是插入成功的数据被自动截取了,值还是12345678,超长的部分被截取掉了
三.总结
1.当varchar类型超长,数据库选择报错还是自动截取取决于是否设置严格模式,严格则会报错
2.实际业务场景中,按需选择,谨慎选择因为设置sql_mode是按照数据库的,不是单表的,可能会影响到其他的表
3.个人建议开启严格模式,因为这样当数据超长时能及时报错发现问题并且进行扩展字段长度,限制提交字段长度等策略,如果非严格,则会被截取,如果是不重要的字段,可能很久之后才发现字段值缺失(被截取了),也无法找回,就造成了数据丢失,最终还是看各自的业务场景